﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace IISLogAnalyzer
{
    public partial class FormProgress : Form
    {
        private DateTime startTime;
        private bool isRunning = false;
        private int isStoring = 0;
        private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        FormIISLogAnalyzer mainForm;
        public FormProgress(FormIISLogAnalyzer formIISLogAnalyzer)
        {
            InitializeComponent();
            mainForm = formIISLogAnalyzer;

            // 初始化进度条的最大值  
            progressBarFiles.Maximum = 100;
            progressBarLines.Maximum = 100;
            progressBarDatabase.Maximum = 100;
        }

        #region 计时器
        private void TimerCallback(CancellationToken token)
        {
            startTime = DateTime.Now;
            lbStartTime.Invoke((MethodInvoker)delegate { lbStartTime.Text = "开始：" + startTime.ToString("yyyy 年 MM 月 dd 日 HH:mm:ss"); });

            while (isRunning && !token.IsCancellationRequested)
            {
                lbEndTime.Invoke((MethodInvoker)delegate { lbEndTime.Text = "实时：" + DateTime.Now.ToString("yyyy 年 MM 月 dd 日 HH:mm:ss"); });

                TimeSpan elapsedTime = DateTime.Now.Subtract(startTime);
                UpdateDisplayTime(elapsedTime);

                Thread.Sleep(1000);
            }
        }

        private void UpdateDisplayTime(TimeSpan elapsedTime)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<TimeSpan>(UpdateDisplayTime), elapsedTime);
            }
            else
            {
                DisplayTimeLabel.Text = " 耗时: " + ConvertSecondsToString(elapsedTime.TotalSeconds);
            }
        }

        public static string ConvertSecondsToString(double seconds)
        {
            int days = (int)(seconds / (24 * 60 * 60));
            seconds %= 24 * 60 * 60;
            int hours = (int)(seconds / (60 * 60));
            seconds %= 60 * 60;
            int minutes = (int)(seconds / 60);
            seconds %= 60;

            // 如果秒数需要保留小数，可以使用 ToString 方法格式化输出  
            string formattedSeconds = seconds.ToString("F0"); // F0 表示不保留小数，如果需要保留特定小数位数，可以改为 "F1"、"F2" 等  

            return $"{days} 天 {hours} 小时 {minutes} 分 {formattedSeconds} 秒";
        }

        #endregion

        #region 多线程处理

        private void EnqueueDataAsync(object isEven, CancellationToken token)
        {
            bool isEvenAnalyzing = (bool)isEven;
            for (int i = isEvenAnalyzing ? 0 : 1; i < TraverseDirectoryFiles.totalFiles; i += 2)
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }

                TraverseDirectoryFiles.filePathsCountIindex++;

                if (TraverseDirectoryFiles.stringQueue.Count >= 1000)
                {
                    Thread.Sleep(5000);//如何序列有1000行没处理，就等待 5 秒。
                }

                // 分析日志并生成SQL语句，然后将它们添加到队列中  
                mainForm.AnalyzeLog(TraverseDirectoryFiles.filePaths[i], progressBarLines, lbFile);

                // 更新进度  
                lock (TraverseDirectoryFiles.SyncRoot)
                {
                    // 更新进度（进度条的范围是0-100）  
                    int progressPercentage = (int)((double)TraverseDirectoryFiles.filePathsCountIindex / TraverseDirectoryFiles.totalFiles * 100);

                    lock (TraverseDirectoryFiles.SyncRoot) // 使用锁来确保线程安全  
                    {
                        progressBarFiles.Invoke((MethodInvoker)delegate { progressBarFiles.Value = progressPercentage; });
                        progressLabel.Invoke((MethodInvoker)delegate { progressLabel.Text = progressPercentage + " % - " + TraverseDirectoryFiles.filePathsCountIindex.ToString() + "/" + TraverseDirectoryFiles.totalFiles.ToString(); });
                    }
                }
            }

            isStoring++;
        }

        private void StoreDataAsync(CancellationToken token)
        {
            string sql;

            while (!token.IsCancellationRequested)
            {
                if (TraverseDirectoryFiles.stringQueue.TryDequeue(out sql))
                {
                    if (!string.IsNullOrEmpty(sql))
                    {
                        TraverseDirectoryFiles.databaseProgress++;

                        // 执行SQL插入操作  
                        SqlLiteHelper.ExecuteSql(sql);

                        // 更新数据库进度  
                        lock (TraverseDirectoryFiles.SyncRoot)
                        {
                            // 更新进度（进度条的范围是0-100）  
                            int progressPercentage = (int)((double)TraverseDirectoryFiles.databaseProgress / TraverseDirectoryFiles.databaseProgressTotal * 100);

                            if (token.IsCancellationRequested)
                            {
                                break;
                            }

                            progressBarDatabase.Invoke((MethodInvoker)delegate { progressBarDatabase.Value = progressPercentage; });
                            lbDatabase.Invoke((MethodInvoker)delegate { lbDatabase.Text = progressPercentage + " % - " + TraverseDirectoryFiles.databaseProgress.ToString() + "/" + TraverseDirectoryFiles.databaseProgressTotal.ToString(); });
                        }
                    }
                }

                if (isStoring == 2 && TraverseDirectoryFiles.stringQueue.IsEmpty)
                {
                    break;
                }
                else
                {
                    Thread.Sleep(100);
                }
            }
        }

        #endregion

        private async void FormProgress_Load(object sender, EventArgs e)
        {
            try
            {
                isRunning = true;
                // 启动计时任务  
                Task timerTask = Task.Run(() => TimerCallback(cancellationTokenSource.Token));

                // 启动分析任务  
                Task analyzeTask1 = Task.Run(() => EnqueueDataAsync(true, cancellationTokenSource.Token));
                // 分析偶数索引的文件  
                Task analyzeTask2 = Task.Run(() => EnqueueDataAsync(false, cancellationTokenSource.Token)); // 分析奇数索引的文件  

                // 启动存储任务  
                Task storeTask = Task.Run(() => StoreDataAsync(cancellationTokenSource.Token));

                // 等待所有任务完成  
                await Task.WhenAll(analyzeTask1, analyzeTask2, storeTask);
                isRunning = false;

                mainForm.BindDate();
                mainForm.BindWebSites();
            }
            catch { }
        }

        private void FormProgress_FormClosing(object sender, FormClosingEventArgs e)
        {
            cancellationTokenSource.Cancel();
            // 等待任务完成或超时，根据需要调整  
            Task.WhenAll(); 
        }
    }
}
